package com.ripcore.model;

import lombok.Data;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 路由器类，用于模拟RIP协议中的路由器行为。
 * 包含路由器的基本信息、邻居关系以及路由表，并提供创建路由更新包的功能。
 */
@Data
public class Router {
    /** 路由器的唯一标识符 */
    private final String id;

    /** 邻居路由器映射，键为邻居路由器ID，值为到该邻居的链路度量值（成本） */
    private final Map<String, Integer> neighbors = new ConcurrentHashMap<>();
    
    /** 路由器的路由表，用于存储和管理路由条目 */
    private final RoutingTable routingTable = new RoutingTable();

    /**
     * 构造函数，初始化路由器ID
     * @param id 路由器的唯一标识符
     */
    public Router(String id) { this.id = id; }

    /**
     * 添加或更新邻居路由器及其链路成本
     * @param neighborId 邻居路由器的ID
     * @param cost 到邻居路由器的链路成本
     */
    public void addNeighbor(String neighborId, int cost) { neighbors.put(neighborId, cost); }
    
    /**
     * 移除指定的邻居路由器
     * @param neighborId 要移除的邻居路由器ID
     */
    public void removeNeighbor(String neighborId) { neighbors.remove(neighborId); }

    /**
     * 创建RIP更新数据包，包含当前路由表的信息
     * @param splitHorizon 是否启用水平分割规则（目前在发送时由引擎处理）
     * @param neighborIdForSplit 用于分割规则的目标邻居ID
     * @return 包含路由条目的RIPPacket对象
     */
    public RIPPacket createUpdatePacket(boolean splitHorizon, String neighborIdForSplit) {
        RIPPacket p = new RIPPacket();
        p.setFromRouterId(id);
        List<RouteEntry> list = new ArrayList<>();
        /**复制路由表中的所有条目到更新数据包中，目的：
         * 数据隔离：通过创建副本而不是直接引用原始条目，防止在传输过程中对原始路由表的意外修改
         * 水平分割准备：注释中提到水平分割/毒性逆转在发送时由引擎处理，这种复制方式为后续处理提供了灵活性
         */
        for (RouteEntry e : routingTable.entries()) {
            // 简单的水平分割/毒性逆转实现在发送时由引擎处理
            RouteEntry copy = new RouteEntry();
            copy.setDestination(e.getDestination());
            copy.setMetric(e.getMetric());
            copy.setNextHop(e.getNextHop());
            copy.setLastUpdated(e.getLastUpdated());
            list.add(copy);
        }
        p.setEntries(list);
        p.setTriggered(false);
        return p;
    }
}